# -*- coding: utf-8 -*-
"""
 ----------------------------------------
|File Name:     http_utils
|Author:        WYT
|date:          2021/5/25
 ----------------------------------------
|  Change Activity:
|                   2021/5/25:
-----------------------------------------
"""
import os
import random
import re
import time

import requests
from fake_useragent import UserAgent, FakeUserAgentError
from requests.exceptions import ConnectionError
from requests.exceptions import Timeout

from util.overWriteMultipartEncoder import overWriteMultipartEncoder
# from util.requests_toolbelt import MultipartEncoder

from util.g import g


class req_attr():

    session = None


def get_ua():
    USER_AGENTS = [
        "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
        "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)",
        "Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
        "Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)",
        "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 2.0.50727; Media Center PC 6.0)",
        "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)",
        "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.04506.30)",
        "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN) AppleWebKit/523.15 (KHTML, like Gecko, Safari/419.3) Arora/0.3 (Change: 287 c9dfb30)",
        "Mozilla/5.0 (X11; U; Linux; en-US) AppleWebKit/527+ (KHTML, like Gecko, Safari/419.3) Arora/0.6",
        "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070215 K-Ninja/2.1.1",
        "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9) Gecko/20080705 Firefox/3.0 Kapiko/3.0",
        "Mozilla/5.0 (X11; Linux i686; U;) Gecko/20070322 Kazehakase/0.4.5",
        "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.8) Gecko Fedora/1.9.0.8-1.fc10 Kazehakase/0.5.6",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.20 (KHTML, like Gecko) Chrome/19.0.1036.7 Safari/535.20",
        "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.11 TaoBrowser/2.0 Safari/536.11",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.71 Safari/537.1 LBBROWSER",
        "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; LBBROWSER)",
        "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E; LBBROWSER)",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.84 Safari/535.11 LBBROWSER",
        "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)",
        "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; QQBrowser/7.0.3698.400)",
        "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)",
        "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SV1; QQDownload 732; .NET4.0C; .NET4.0E; 360SE)",
        "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)",
        "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1",
        "Mozilla/5.0 (iPad; U; CPU OS 4_2_1 like Mac OS X; zh-cn) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5",
        "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0b13pre) Gecko/20110307 Firefox/4.0b13pre",
        "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:16.0) Gecko/20100101 Firefox/16.0",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11",
        "Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10"
    ]
    return random.choice(USER_AGENTS)


def get_proxies():
    data = [
        {"https": "178.134.208.126:50824"},
        {"https": "60.170.152.46:38888"}]
    return random.choice(data)


def send_post(url:str, headers:dict={}, data:dict={}, json:dict={}, params:dict={},
              file_path:str=None, file_key:str="upload", driver=None):
    try:
        num = 0
        while True:
            try:
                res = None
                text = None
                multi_data = None
                if headers == {}:
                    headers = g.headers
                    headers["User-Agent"] = get_ua()
                    headers["Cookie"] = "; ".join("" if not v else "{}={}".format(k, v) for k, v in g.cookie.items())
                # 处理请求头 将请求头还原成正常的情况
                if "Content-Type" in headers:
                    del headers["Content-Type"]
                # if headers.get("Connection") != "Close":
                #     headers["Connection"] = "Close"
                if file_path is not None:
                    # 处理附件
                    path, filename = os.path.split(file_path)
                    f, ext = os.path.splitext(filename)
                    file_type = "application/"
                    if ext == ".pdf":
                        file_type += "pdf"
                    if ext == ".png":
                        file_type += "X-png"
                    data["{}".format(file_key)] = (filename, open(file_path, "rb"), file_type)
                    multi_data = overWriteMultipartEncoder(fields=data)
                    # 处理请求头 将 请求头改为可以上传附件的情况
                    headers["Content-Type"] = multi_data.content_type
                    # print(headers)
                res = requests.post(
                    # url, proxies=get_proxies(), headers=headers,
                    url, headers=headers,
                    data=data if multi_data is None else multi_data, json=json, params=params,
                    allow_redirects=False)
                status_code = res.status_code
                text = res.content.decode("utf-8")
                res.close()
                if status_code == 302 or status_code == 307:
                    if not params:
                        params["ad_check"] = "1"
                    cookie_dict = dict(res.cookies)
                    for k, v in cookie_dict.items():
                        if k in g.cookie:
                            if v:
                                g.cookie[k] = v

                elif status_code == 200:
                    token_pattern = '.*?name="token".value="(.*?)".*?'
                    result = re.findall(token_pattern, text, re.S)
                    if len(result) == 1:
                        g.token = result[0]
                    message_pattern = '.*?var.alertMessage.=."(.*?)".*?'
                    message = re.findall(message_pattern, text, re.S)
                    # 获取 token
                    if not text or u"未登录或登录超时" in text:
                        print(g.cookie)
                        print(url)
                        print("text: {}".format(text))
                        if driver is not None:
                            driver.quit()
                        os._exit(0)
                    else:
                        return {"text": text, "message": "".join(message), "token": "".join(result)}
                else:
                    print("status_code: {}".format(status_code))
                    print("data: {}".format(data))
                    print("response-headers: {}".format(res.headers))
                    print("response-cookies: {}".format(res.cookies))
            except (ConnectionError, Timeout) as err:
                g.logger.error("请求超时: ")
                time.sleep(3)
                num += 1
                if num > 8:
                    if driver is not None:
                        driver.quit()
                    os._exit(0)
            else:
                if res and status_code == 200:
                    if not text or u"未登录或登录超时" in text:
                        time.sleep(1.5)
                    else:
                        break
    except Exception as err:
        err_msg = "{} file:{} lines:{} --- data: {}".format(
            err, err.__traceback__.tb_frame.f_globals["__file__"],
            err.__traceback__.tb_lineno, data)
        raise Exception(err_msg)


def send_get(url:str, headers:dict={}, data:dict={}, json:dict={}, params:dict={}, driver=None):
    try:
        num = 0
        while True:
            try:
                if headers == {}:
                    headers = g.headers
                    headers["User-Agent"] = get_ua()
                    headers["Cookie"] = "; ".join(
                        "" if not v else "{}={}".format(k, v) for k, v in g.cookie.items())
                if "Content-Type" in headers:
                    del headers["Content-Type"]
                # if headers.get("Connection") != "Close":
                #     headers["Connection"] = "Close"
                res = requests.get(
                    # url, proxies=get_proxies(), headers=headers, data=data, json=json, params=params,
                    url, headers=headers, data=data, json=json, params=params,
                    allow_redirects=False)
                text = res.content.decode("utf-8")
                status_code = res.status_code
                res.close()
                if status_code == 302 or status_code == 307:
                    if not params:
                        params["ad_check"] = "1"
                    cookie_dict = dict(res.cookies)
                    for k, v in cookie_dict.items():
                        if k in g.cookie:
                            if v:
                                g.cookie[k] = v

                elif status_code == 200:
                    token_pattern = '.*?name="token".value="(.*?)".*?'
                    result = re.findall(token_pattern, text, re.S)
                    if len(result) == 1:
                        g.token = result[0]
                    message_pattern = '.*?var.alertMessage.=."(.*?)".*?'
                    message = re.findall(message_pattern, text, re.S)
                    # 获取 token
                    if not text or u"未登录或登录超时" in text:
                        print(g.cookie)
                        print(url)
                        print("text: {}".format(text))
                        if driver is not None:
                            driver.quit()
                        os._exit(0)
                    else:
                        return {"text": text, "message": "".join(message), "token": "".join(result)}
                else:
                    print("status_code: {}".format(status_code))
                    print("data: {}".format(data))
                    print("response-headers: {}".format(res.headers))
                    print("response-cookies: {}".format(res.cookies))
            except (ConnectionError, Timeout) as err:
                time.sleep(3)
                g.logger.error("请求超时: ")
                num += 1
                if num > 8:
                    if driver is not None:
                        driver.quit()
                    os._exit(0)
            else:
                if res and status_code == 200:
                    if not text or u"未登录或登录超时" in text:
                        time.sleep(1.5)
                    else:
                        break
    except Exception as err:
        err_msg = "{} file:{} lines:{} --- data: {}".format(
            err, err.__traceback__.tb_frame.f_globals["__file__"],
            err.__traceback__.tb_lineno, data)
        raise Exception(err_msg)
